package com.uuah.server.config.registry;

import java.util.Collection;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.uuah.config.i18n.CoreMessages;
import com.uuah.exception.UuahRuntimeException;
import com.uuah.exception.lifecycle.InitialisationException;
import com.uuah.server.api.config.registry.IRegistry;
import com.uuah.server.exception.registry.RegistrationException;
import com.uuah.utils.UUID;

public abstract class AbstractRegistry implements IRegistry {
	private String id;

	protected transient Logger logger = LoggerFactory.getLogger(getClass());

	protected AbstractRegistry(String id) {
		if (id == null) {
			throw new UuahRuntimeException(CoreMessages
					.objectIsNull("RegistryID"));
		}
		this.id = id;
	}

	public final synchronized void dispose() {
		try {
			doDispose();
		} catch (Exception e) {
			logger.error("Failed to cleanly dispose: " + e.getMessage(), e);
		}
	}

	abstract protected void doInitialise() throws InitialisationException;

	abstract protected void doDispose();

	public final void initialise() throws InitialisationException {
		if (id == null) {
			logger.warn("No unique id has been set on this registry");
			id = UUID.getTimeBasedUUIDString();
		}
		try {
			doInitialise();
		} catch (InitialisationException e) {
			throw e;
		} catch (Exception e) {
			throw new InitialisationException(e, this);
		}
	}

	public Object lookupObject(Class type) throws RegistrationException {
		Collection objects = lookupObjects(type);

		if (objects.size() == 1) {
			return objects.iterator().next();
		} else if (objects.size() > 1) {
			throw new RegistrationException("More than one object of type "
					+ type + " registered but only one expected.");
		} else {
			return null;
		}
	}

	public final String getRegistryId() {
		return id;
	}
}
